package cate.game.framework;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cp.game.framework.ManyGameConfig;
import cp.solution.business.cloud.CloudMongoEntity;
import cp.solution.business.cloud.CloudServerEntity;
import cp.solution.business.game.boot.GameSrvBootstrap;
import cp.solution.business.game.conf.GameSrvEntity;
import cp.solution.business.sys.env.EnvironmentVarSets;
import cp.solution.fax.FaxTags;
import cp.solution.util.collection.ListKit;
import easy.java.practice.errorcode.EcException;
import easy.java.time.DateTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 游戏配置
 */
@Slf4j
public class GameConfig {

    /**
     * 共享配置
     */
    private ManyGameConfig share;

    public ManyGameConfig share() {
        return this.share;
    }

    public int srvId;

    public Set<Integer> eatenSrvIds = Sets.newHashSet();

    public List<Integer> getAllSrvIds() {
        List<Integer> allSrvIds = Lists.newArrayList(srvId);
        if (!CollectionUtils.isEmpty(eatenSrvIds)) {
            allSrvIds.addAll(eatenSrvIds);
        }
        return allSrvIds;
    }

    public GameSrvEntity gs;

    public CloudServerEntity cs;

    public CloudMongoEntity mongo;

    public int redirect;

    public void setUpEatenSrvIds() {
        if (gs != null) {
            String recentEaten = gs.getRecentEaten();
            if (StringUtils.isNotBlank(recentEaten)) {
                String[] ids;
                if (recentEaten.contains("#")) {
                    // 2022-12-01 之后， 就会采取#
                    ids = StringUtils.split(recentEaten, "#");
                } else {
                    // 现在这个是兼容性修改
                    ids = StringUtils.split(recentEaten, ":");
                }
                if (Objects.nonNull(ids) && ArrayUtils.isNotEmpty(ids)) {
                    Arrays.stream(ids)
                            .mapToInt(Integer::parseInt)
                            .forEach(this.eatenSrvIds::add);
                }
            }
        }
    }

    public boolean isLocal(int srvId) {
        return srvId == -1 || srvId == this.srvId || this.eatenSrvIds.contains(srvId);
    }

    public boolean isRemote(int srvId) {
        return !isLocal(srvId);
    }

    public void setup(ManyGameConfig share) {
        this.share = share;
    }

    public boolean isAllowGm() {
        return gs.isAllowGm();
    }

    public boolean isMiniSH() {
        return gs.isWxshEnabled();
    }

    /**
     * 允许创建新角色
     */
    public boolean allowCreateRole() {
        return true;
    }

    public long getOpenTime() {
        if (gs == null || gs.getOpenTime() == null) {
            return 0;
        }
        return gs.getOpenTime().getTime();
    }

    /**
     * 获取合服时间
     */
    public long getMergeTime() {
        if (gs == null || gs.getMergeTime() == null) {
            return 0;
        }
        return gs.getMergeTime().getTime();
    }

    public boolean isCrossEnabled() {
        return gs != null && StringUtils.isNotBlank(gs.getCrossCode());
    }

    public boolean isZoneEnabled() {
        return gs != null && StringUtils.isNotBlank(gs.getZoneCode());
    }

    private long lastReloadTime;

    /**
     * 随意重载
     */
    public void reloadOptionally(GameFacilities facilities) {
        long now = System.currentTimeMillis();
        if (lastReloadTime <= 0) {
            lastReloadTime = now + (long) (60_000 * Math.random());
            log.info("随意重载设定初始时间 srvId={} 设定上次加载时间为{}", this.srvId, DateTool.instance().format(lastReloadTime));
            return;
        }
        if (now - lastReloadTime < 60_000) {
            log.debug("无需重新读取配置，距离上次间隔只有 {} 秒", (now - lastReloadTime) / 1000);
            return;
        }
        log.info("重新读取配置开始");
        lastReloadTime = now;
        try {
            EnvironmentVarSets.getInstance().readWith(facilities.getApi().pc());
            GameSrvBootstrap bootstrap = facilities.getApi().pc().console.gameSrv.bootstrap(this.srvId);
            if (bootstrap != null) {
                // 此处还可以更进一步判断哪些发生了变化
                if (!StringUtils.equals(this.gs.getCrossCode(), bootstrap.getGs().getCrossCode())) {
                    log.error("{}的crossCode发生变化 {} -> {}", this.srvId, this.gs.getCrossCode(), bootstrap.getGs().getCrossCode());
                    log.error("按照当前逻辑，这是不应该发生的！已被拒绝");
                    return;
                }
                this.gs = bootstrap.getGs();
            }
        } catch (Exception e) {
            log.error("随意重载bootstrap失败", e);
        }
    }

    private Map<String, List<Object>> faxClientTags;

    public Map<String, List<Object>> getFaxClientTags() {
        if (faxClientTags == null) {
            if (gs == null) {
                throw new EcException("GameSrv配置尚未获得");
            }
            faxClientTags = new HashMap<>();
            faxClientTags.put(FaxTags.TAG_GAME_SRV_ID, ListKit.toList(gs.getId()));
        }
        return faxClientTags;
    }
}
